package elitech.vietnam.weatherfashion.weatherservice;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

class OpenWeatherMapService {

	static final String WEATHER_API_URL = "http://api.openweathermap.org/data/2.5/forecast/";
	// static final String WEATHER_API_URL =
	// "http://api.openweathermap.org/data/2.5/weather/";
	public static final String MODE_XML = "xml";
	public static final String MODE_JSON = "json";
	public static final String UNIT_CELCIUS = "metric";
	public static final String UNIT_FEHRENHEIT = "imperial";

	public WeatherObject getWeatherByCity(String city, String unit) {
		if (city == null)
			return null;
		city = city.trim().replace(' ', '_');

		try {

			String urlStr = WEATHER_API_URL + "daily?q=" + city + "&mode=" + MODE_XML + "&units=" + unit + "&cnt=7";
			Log.w("getWeatherByCity", urlStr);
			Document doc = getDocument(urlStr);
			if (doc == null)
				return null;

			WeatherObject result = getWeatherInfo(doc);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public WeatherObject getWeatherByCity(String city) {
		return getWeatherByCity(city, UNIT_CELCIUS);
	}

	public WeatherObject getWeatherByLocation(String lat, String lon, String unit) {

		try {

			String urlStr = WEATHER_API_URL + "daily?lat=" + lat + "&lon=" + lon + "&mode=xml" + "&units=" + unit + "&cnt=7";
			Log.w("getWeatherByLocation", urlStr);
			Document doc = getDocument(urlStr);
			if (doc == null)
				return null;

			WeatherObject result = getWeatherInfo(doc);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public WeatherObject getWeatherByLocation(String lat, String lon) {

		return getWeatherByLocation(lat, lon, UNIT_CELCIUS);
	}

	public WeatherObject getWeatherByCityId(int cityId) {

		try {

			String urlStr = WEATHER_API_URL + "daily?id=" + cityId + "&mode=xml" + "&units=" + UNIT_CELCIUS + "&cnt=7";
			Log.w("getWeatherByCityId", urlStr);
			Document doc = getDocument(urlStr);
			if (doc == null)
				return null;

			WeatherObject result = getWeatherInfo(doc);
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private Document getDocument(String urlStr) throws MalformedURLException, ParserConfigurationException, SAXException, IOException {
		try {
			URL url = new URL(urlStr);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new InputSource(url.openStream()));
			doc.getDocumentElement().normalize();
			return doc;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	private WeatherObject getWeatherInfo(Document doc) {

		WeatherObject result = new WeatherObject();

		String cityStr = doc.getElementsByTagName("name").item(0).getTextContent();
		result.setCity(cityStr);
		String countryStr = doc.getElementsByTagName("country").item(0).getTextContent();
		result.setCountry(countryStr);

		ArrayList<WeatherDayObject> listDayWeather = new ArrayList<WeatherDayObject>();

		NodeList dayNodes = doc.getElementsByTagName("time");
		for (int i = 0; i < dayNodes.getLength(); i++) {

			Element day = (Element) dayNodes.item(i);

			String typeStr = day.getElementsByTagName("symbol").item(0).getAttributes().getNamedItem("name").getNodeValue();

			Node template = day.getElementsByTagName("temperature").item(0);
			String tempUpStr = template.getAttributes().getNamedItem("max").getNodeValue();

			String tempDownStr = template.getAttributes().getNamedItem("min").getNodeValue();

			String tempAveStr = template.getAttributes().getNamedItem("eve").getNodeValue();

			String tempDayStr = template.getAttributes().getNamedItem("day").getNodeValue();

			String tempNightStr = template.getAttributes().getNamedItem("night").getNodeValue();

			String dayStr = day.getAttributes().getNamedItem("day").getNodeValue();

			WeatherDayObject weatherDay = new WeatherDayObject(typeStr, tempUpStr, tempDownStr, tempAveStr, tempDayStr, tempNightStr, dayStr);

			if (i == 0)
				result.setToday(weatherDay);
			else
				listDayWeather.add(weatherDay);

		}
		result.setListDay(listDayWeather);
		return result;
	}

}
